#include "iodialog.h"
#include "ui_iodialog.h"

IODialog::IODialog(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::IODialog)
{
    ui->setupUi(this);
    initChinese();
    initTestXlsx();
    initUI();
    initSql();
    initData();
    //loadData();
    //loadIntoUI();
    connectSignalAndSlot();
}

void IODialog::initUI()
{
    //补充占位文字
    ui->cardNumEdit->setPlaceholderText("16 or 32");
    ui->pinEdit->setPlaceholderText("chinese pin name");
    ui->pinNameEdit->setPlaceholderText("english pin name");
    ui->xlsxPathEdit->setPlaceholderText("input Xlsx File Path");
    ui->filePathLabel->setPlaceholderText("input Folder Path");     //这里一般电机文件和工位文件放在同一个文件夹
}

void IODialog::initSql()
{
    dataBase = QSqlDatabase::addDatabase("QSQLITE");
    dataBase.setDatabaseName("pinData.db");

    // 2. 打开数据库
    if (!dataBase.open()) {
        qDebug() << "dataBase connected failed! " << dataBase.lastError().text();
        return;
    }

    qDebug() << "dataBase connected successfully!";

    // 3. 创建表
    QSqlQuery query;
//    QString sql = "CREATE TABLE IF NOT EXISTS datas ("
//                  "row integer, "
//                  "col integer, "
//                  "type integer, "
//                  "pinName TEXT NOT NULL UNIQUE, "
//                  "signal TEXT NOT NULL, "
//                  "functionConnect TEXT NOT NULL,"
//                  "hardwareConnect TEXT NOT NULL,"
//                  "PRIMARY KEY (row, col));";
//    if (!query.exec(sql))
//    {
//        qDebug() << "failed to create table: " << query.lastError().text();
//        dataBase.close();
//        return;
//    }
    //创建IO总数据表
    QString sql = "CREATE TABLE IF NOT EXISTS IOData ("
                  "pinName TEXT NOT NULL PRIMARY KEY, "
                  "signal TEXT NOT NULL); ";
    if (!query.exec(sql))
    {
        qDebug() << "failed to create table: " << query.lastError().text();
        dataBase.close();
        return;
    }
    qDebug() << "dataBase init successfully!";
}

void IODialog::initData()
{
//    //初始化数组
//    inputData.resize(1);
//    inputData[0].resize(32);
//    outputData.resize(1);
//    outputData[0].resize(32);

    //初始化hash
    QSqlQuery query;
    if (!query.exec("SELECT * FROM IOData")) {
        qDebug() << "Error executing query: " << query.lastError().text();
        return;
    }

    // 遍历查询结果，读取每一行数据
    while (query.next()) {
        QString pinName = query.value(0).toString();
        QString signal = query.value(1).toString();
        //将数据库中数据放到hash中，方便后续查找
        hash[pinName] = signal;
    }

    type = INPUT;
    cardIdx = 0;
    curCardNumIdx = 0;
    curCardNum = 0;
    inputDataSize = 0;
    outputDataSize = 0;
}

void IODialog::connectSignalAndSlot()
{
    connect(ui->confirmBtn,SIGNAL(clicked()),this,SLOT(onConfirmBtnClicked()));
    connect(ui->writeBtn,SIGNAL(clicked()),this,SLOT(onWriteBtnClicked()));
    connect(ui->addOrModifyBtn,SIGNAL(clicked()),this,SLOT(onAddOrModifyBtnClicked()));
    //connect(ui->writeFileBtn,SIGNAL(clicked()),this,SLOT(onWriteFileBtnClicked()));
    connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(onComboBoxIndexChanged()));
    connect(ui->initMotorBtn,SIGNAL(clicked()),this,SLOT(onInitMotorBtnClicked()));
    connect(ui->prevPageBtn,SIGNAL(clicked()),this,SLOT(onPrevPageBtnClicked()));
    connect(ui->nextPageBtn,SIGNAL(clicked()),this,SLOT(onNextPageBtnClicked()));
    connect(ui->modifycardNumBtn,SIGNAL(clicked()),this,SLOT(onModifyCardNumBtnClicked()));
    connect(ui->loadByXlsxBtn,SIGNAL(clicked()),this,SLOT(onLoadXlsxBtnClicked()));
}

//将数据库中上次写入的数据分别写入两个数组中             -- 暂时不使用
void IODialog::loadData()
{
        // 执行查询，获取所有数据
        QSqlQuery query;
        if (!query.exec("SELECT * FROM datas")) {
            qDebug() << "Error executing query: " << query.lastError().text();
            return;
        }

        // 遍历查询结果，读取每一行数据
        while (query.next()) {
            int row  = query.value(0).toInt();
            int col  = query.value(1).toInt();
            Type type  = query.value(2).toInt() == 0 ? INPUT : OUTPUT;
            QString pinName = query.value(3).toString();
            QString signal = query.value(4).toString();
            QString functionConnect = query.value(5).toString();
            QString hardConnect = query.value(6).toString();
//            //将数据库中数据放到hash中，方便后续查找
//            hash[pinName] = signal;

            IOData* data = new IOData(pinName,signal,functionConnect,hardConnect);
            //扩容加填入
            if(type == INPUT)
            {
                int sz = inputData.size();
                if(row >= sz)
                {
                    inputData.resize(row+1);
                    for(int i = sz-1;i<=row;++i)
                    {
                        inputData[i].resize(32);
                    }
                }
                inputData[row][col] = data;
            }
            else if(type == OUTPUT)
            {
                int sz = outputData.size();
                if(row >= sz)
                {
                    outputData.resize(row+1);
                    for(int i = sz-1;i<=row;++i)
                    {
                        outputData[i].resize(32);
                    }
                }
                outputData[row][col] = data;
            }
        }
}

//在初始化阶段将已经加载进来的数组中的数据，把第一卡的数据先加载到界面中，并完成部分界面的初始化         -- 暂时不使用
void IODialog::loadIntoUI()
{
     qDebug() << "loadIntoUI start";
    int col = inputData[0].size();
    for(int i = 0;i<col;++i)
    {
        //if(inputData[0][i].first == "") break;          //这里可能是第一次
        //addItem(inputData[0][i],inputData[0][i]);
    }
    ui->cardNumEdit->setText(QString::number(col));
    qDebug() << "loadIntoUI end";
}

void IODialog::initChinese()
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8") );
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
}

void IODialog::initTestXlsx()
{
//    QXlsx::Document xlsx;
//    xlsx.write(1, 2, "Hello Qt!");
//    xlsx.write(2, 2, QString::fromLocal8Bit("中文"));
//    xlsx.saveAs("Text.xlsx");
}

//添加元素到ListWidget中
void IODialog::addItem(const IOData* data)
{
    //已经超出了卡的数量
    qDebug() << "curCardNumIdx: " << curCardNumIdx << "  curCardNum: " << curCardNum;
    if(curCardNum == 0)
    {
        //这里是切换了界面，但是没有设置卡的数量
        QMessageBox::warning(NULL,"Warning","please set cardNum");
        return;
    }
    //处理功能连接，硬件连接并加载到listWidget中
    ListWidget* listItemWidget = new ListWidget(this);
    listItemWidget->setListWidgetData(data);
    QListWidgetItem* item = new QListWidgetItem(ui->listWidget);
    //绑定对应的槽函数，如果该控件修改了，就通知修改对应的数组中的内容
    connect(listItemWidget,SIGNAL(labelTextChanged(QString,QString)),this,SLOT(onLabelTextChanged(QString,QString)));
    item->setSizeHint(QSize(listItemWidget->width(),listItemWidget->height()));
    ui->listWidget->setItemWidget(item,listItemWidget);

//    QStandardItem* item = new QStandardItem();
//    item->setData(QVariant::fromValue(listItemWidget));
//    model->appendRow(item);

    ++curCardNumIdx;
    //这里如果添加完该卡的最后一个数据，就直接切换页面
    if(curCardNumIdx == curCardNum)
    {
        curCardNumIdx = 0;
        curCardNum = 0;
        ++cardIdx;
        ui->listWidget->clear();
        ui->cardNumEdit->clear();
    }
}

//获取功能数和硬件连接字符串
void IODialog::getFuncAndHardware(QString &funcStr, QString &hardStr,const QString& pinName)
{
    //根据中文名称来解析出对应的信息
    if(pinName.isEmpty())     funcStr = "9";
    setFunction(pinName,funcStr);
    //硬件连接
    setHardwareConnect(hardStr);
}

//设置引脚的功能
void IODialog::setFunction(const QString &pinName, QString &func)
{
    //qDebug() << "setFunction: pinName: " << pinName;
    QString originStr = "原点";
    if(pinName.contains(originStr))
    {
        func = "3";
        return;
    }
    QString testStr = "测试";
    //qDebug() << "testStr: " << testStr;
    if(pinName.contains(testStr))
    {
        func = "2";
        return;
    }
    QString inputStr = "INPUT";
    QString outputStr = "OUTPUT";
    if(pinName.contains(inputStr) || pinName.contains(outputStr))
    {
        func = "9";
        return;
    }
    QVector<QString> keywords;
    keywords.append("ok");
    keywords.append("ng");
    keywords.append("视觉");
    keywords.append("字符");
    keywords.append("方向");
    keywords.append("打印");
    keywords.append("3D");
    for (int i = 0;i<keywords.size();++i)
    {
        if (pinName.contains(keywords[i],Qt::CaseInsensitive))
        {
            func = "1";
            return;
        }
     }
    func = "0";
}

//设置硬件连接
void IODialog::setHardwareConnect(QString &hardStr)
{
    //ect.0.is.%%.din.%%.in    ect.0.is.4%.dout.%%.out
    char buf[64];
    if(type == INPUT)
    {
        sprintf(buf,"%d = ect.0.is.%d.din.%02d.in",inputDataSize,41+cardIdx,curCardNumIdx);
    }
    else
    {
        //OUTPUT
        sprintf(buf,"%d = ect.0.is.%d.dout.%02d.out",outputDataSize,41+cardIdx,curCardNumIdx);
    }
    hardStr = buf;
}

//改变页数的时候需要加载新的页面   -- 返回失败说明没有切换
bool IODialog::changePage(QVector<QVector<IOData *> > &datas,int index)
{
    int sz = datas.size();
    //qDebug() << "sz: " << sz <<"  index: " << index;
    if(sz == 0 || index > sz) return false;        //没有数据或者在最后一页的下一页没有数据
    //把界面数据清除
    ui->listWidget->clear();                            //todo：这里的操作可能存在问题，暂时这么做
    if(index == sz)             //跳到最新一页
    {
        curCardNumIdx = curCardNum = 0;
        ui->cardNumEdit->setText(QString::number(curCardNum));           //设置当前卡的数量
        return true;
    }
    //把第index页数据加载到页面
    for(int i = 0;i<datas[index].size();++i)
    {
        IOData* data = datas[index][i];
        ListWidget* listItemWidget = new ListWidget(this);
        //为了随时可以修改
        connect(listItemWidget,SIGNAL(labelTextChanged(QString,QString)),this,SLOT(onLabelTextChanged(QString,QString)));
        listItemWidget->setListWidgetData(data);
        QListWidgetItem* item = new QListWidgetItem(ui->listWidget);
        item->setSizeHint(QSize(listItemWidget->width(),listItemWidget->height()));
        ui->listWidget->setItemWidget(item,listItemWidget);
    }
    curCardNum = datas[index].size();
    curCardNumIdx = curCardNum;
    ui->cardNumEdit->setText(QString::number(curCardNum));           //设置当前卡的数量
    return true;
}

//修改文件，完成初始化工作      -- number为该初始化的数字
void IODialog::modifyMotorAndStationFile(const QString &filePath,const QString& startStr,int number)
{
        // 打开文件用于读取
        QFile file(filePath);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug() << "can not open file to read: " << filePath;
            return;
        }

        QTextStream in(&file);
        QString content;
        bool startModify = false; // 标志变量，用于控制何时开始修改
        while (!in.atEnd())
        {
            QString line = in.readLine();
            // 检查是否是特定的常量字符串
            if (line.trimmed() == startStr)
            {
                startModify = true; // 开始修改
                content += line + "\n"; // 保留该行
                continue;
            }

            if (startModify)
            {
                if (line.contains('['))   // 如果遇到新的 [ 字符，停止修改
                {
                    startModify = false;
                    content += line + "\n"; // 保留该行
                    continue;
                }
                else
                {
                    int pos = line.indexOf('=');
                    if (pos != -1)
                    {
                        QString key = line.left(pos+1);                                                         // 获取等号左边的英文(包括等号)
                        QString modifiedLine = key + QString::number(number);            // 将数字部分替换为 -1
                        content += modifiedLine + "\n";                                                     // 将修改后的行添加到内容中
                    }
                    else
                    {
                        content += line + "\n"; // 如果格式不符合，保留原行
                    }
                }
            }
            else
            {
                content += line + "\n"; // 如果尚未开始修改，保留原行
            }
        }
        file.close();

        // 打开文件用于写入
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            qDebug() << "can not open file to write: " << filePath;
            return;
        }

        QTextStream out(&file);
        out << content; // 写入修改后的内容
        file.close();

        qDebug() << "finish init file!";
}

//将新增引脚和字母添加到数据库中
void IODialog::insertPinIntoDataBase()
{
    QSqlQuery query;
    foreach (const QString& key , newPinHash.keys())
    {
        QString value =newPinHash.value(key);
        QString insertQuery = QString("insert into %1 (pinName, signal) values ( :key, :value)").arg("IOData");
        query.prepare(insertQuery);
        query.bindValue(":key",key);
        query.bindValue(":value",value);
        if (!query.exec())
        {
              qDebug() << "插入数据失败：" << query.lastError().text();
         }
    }
}

//将两个数组中的信息写入到文件中
void IODialog::loadDataIntoFile()
{
    //通过多个String把每一部分的内容存储起来，最后拼接到一起写入数据库中
    const QString filePath = "/home/u/cnc/configs/ppmc/newio.ini";
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qWarning("Cannot open file for writing: %s", qPrintable(file.errorString()));
        return;
    }

    QTextStream out(&file);

    // 收集所有内容
    QVector<QString> inPutHardwareConnects,outPutHardwareConnects;
    //int inPutNum = 0,outPutNum = 0;

    foreach (const QVector<IOData*>& row , inputData)
    {
        foreach (const IOData* ioData , row)
        {
            inPutHardwareConnects.append(ioData->_hardwareConnect);
            //++inPutNum;
        }
    }

    foreach (const QVector<IOData*>& row , outputData)
    {
        foreach (const IOData* ioData , row)
        {
            outPutHardwareConnects.append(ioData->_hardwareConnect);
            //++outPutNum;
        }
    }
    //写入FLAG
    out << "[FLAG]\n";
    out << "IOCONTROL=1\n";
    //写入MAX
    out << "[MAX]\n";
//    out << "IN=" << QString::number(inPutNum) << "\n";
//    out << "OUT=" + QString::number(outPutNum) << "\n";
    out << "IN=" << QString::number(inputDataSize) << "\n";
    out << "OUT=" + QString::number(outputDataSize) << "\n";
    out << "\n";

    //写入输入硬件连接
    out << "[IN]\n";
    foreach(const QString& data , inPutHardwareConnects)
    {
        out << data << "\n";
    }
    out << "\n";
    //写入输出硬件连接
    out << "[OUT]\n";
    foreach(const QString& data , outPutHardwareConnects)
    {
        out << data << "\n";
    }
    out << "\n";
    //写入每一个IO点的数据
    int num = 0;        //用来记录节点数量
    foreach (const QVector<IOData*>& row , inputData)
    {
        foreach (const IOData* ioData , row)
        {
            out << "[INPUT_" + ioData->_signal + "]\n";
            out << "NAME = " + ioData->_pinName + "\n";
            out << "NUM = " + QString::number(num) + "\n";
            out << "POL = 0" << "\n";
            out << "DEFAULT = 0" << "\n";
            out << "SIGNAL_NAME = " + ioData->_signal + "\n";
            out << "PIN1 = " + ioData->_functionConnect + "\n\n";
            ++num;
        }
    }
    num = 0;
    foreach (const QVector<IOData*>& row , outputData)
    {
        foreach (const IOData* ioData , row)
        {
            out << "[OUTPUT_" + ioData->_signal + "]\n";
            out << "NAME = " + ioData->_pinName + "\n";
            out << "NUM = " + QString::number(num) + "\n";
            out << "POL = 0" << "\n";
            out << "DEFAULT = 0" << "\n";
            out << "SIGNAL_NAME = " + ioData->_signal + "\n";
            out << "PIN1 = " + ioData->_functionConnect + "\n\n";
            ++num;
        }
    }

    file.close();
}

//对输入输出数组进行扩容
void IODialog::resizeVector(QVector<QVector<IOData *> > &data)      //该函数在自动化输入的时候再使用
{
    if(cardIdx >= data.size())      //新的一页
    {
        data.resize(cardIdx+1);
    }
    //扩容当前列
    data[cardIdx].resize(curCardNum);        //todo：如果是缩容，那这里会存在内存泄露
}

//加载数据到数组中并展示到页面
void IODialog::loadDataintoVectorAndShow(const QString &pinName, const QString &signal)
{
    QString funcStr ,hardwareStr;
    getFuncAndHardware(funcStr,hardwareStr,pinName);
    IOData* data = new IOData(pinName,funcStr,signal,hardwareStr);
    //检测新界面是否读取有卡数
    if(curCardNum == 0)
    {
        QMessageBox::warning(NULL,"Warning","please set cardNum");
        return;
    }
    if(type == INPUT)
    {
        inputData[cardIdx][curCardNumIdx] = data;
        ++inputDataSize;
    }
    else
    {
        outputData[cardIdx][curCardNumIdx] = data;
        ++outputDataSize;
    }
    addItem(data);
}

void IODialog::modifyVectorByIndex(QVector<QVector<IOData *> > &data, int row, int col, const QString& label)
{
    int index = label[0].digitValue();
    QString modifyText = label.mid(1);
    switch(index)
    {
    case 0:
        data[row][col]->_pinName = modifyText;
        break;
    case 1:
        data[row][col]->_signal = modifyText;
        break;
    case 2:
        data[row][col]->_functionConnect = modifyText;
        break;
    default:
        //这里硬件连接不允许修改
        qDebug() << "can not modify By input";
        break;
    }
}

void IODialog::onConfirmBtnClicked()
{
    //拿到输入框中的中文去hash中查找
    QString text = ui->chineseNameEdit->text();
    if(hash.contains(text))
    {
        ui->resultLabel->setText(hash[text]);
    }
    else
    {
        ui->resultLabel->setText("none");           //找不到
    }
}


void IODialog::onWriteBtnClicked()
{
    //根据前面输入的中文名和搜索结果来填写到ListWidget中
    //如果已经满了，需要修改卡数才能继续添加
    if(curCardNumIdx  == curCardNum)
    {
        QMessageBox::warning(NULL,"Warning","curCard is fulled");
        return;
    }
    QString pinName = ui->chineseNameEdit->text();
    QString pinEnglishName = ui->resultLabel->text();
    ui->chineseNameEdit->clear();
    ui->resultLabel->clear();
    //将内容添加到ListView中
    //对pinName为"",以及信号为none的情况做处理
    if(pinName == "")
    {
        char buf[64];
        if(type == INPUT) sprintf(buf,"INPUT_%d_%02d",cardIdx+1,curCardNumIdx+1);
        else sprintf(buf,"OUTPUT_%d_%02d",cardIdx+1,curCardNumIdx+1);
        pinName = buf;
        pinEnglishName =buf;
    }
    else if(pinEnglishName == "none" || pinEnglishName == "")
    {
        char buf[64];
        if(type == INPUT) sprintf(buf,"INPUT_%d_%02d",cardIdx+1,curCardNumIdx+1);
        else sprintf(buf,"OUTPUT_%d_%02d",cardIdx+1,curCardNumIdx+1);
        pinEnglishName =buf;
    }
    qDebug() << "pinName: " << pinName << " signal: " << pinEnglishName;
    //收集全部的数据写入到数组中，然后再写入到界面上
    loadDataintoVectorAndShow(pinName,pinEnglishName);
}

void IODialog::onAddOrModifyBtnClicked()
{
    //查找hash中的数据，如果有就更新，如果没有就往新的hash中添加
    QString pinName = ui->pinEdit->text();
    QString pinEnglishName = ui->pinNameEdit->text();
    ui->pinEdit->clear();
    ui->pinNameEdit->clear();
    if(hash.contains(pinName))
    {
        hash[pinName] = pinEnglishName;             //修改
    }
    else
    {
        //新增
        newPinHash[pinName] = pinEnglishName;
    }
    //将内容添加到ListWidget中
    loadDataintoVectorAndShow(pinName,pinEnglishName);
}

void IODialog::onWriteFileBtnClicked()                  //不使用了，采用其他方式
{
    //遍历ListWidget中的内容，将内容写入vector中即可，后续在关闭程序的时候再写入文件中
    int count = ui->listWidget->count();
    if(count < curCardNum)
    {
        QMessageBox::warning(NULL,"Warning","inputCount less than cardCount,please continue typing");
        return;
    }
    for(int i = 0;i<count;++i)
    {
        QListWidgetItem* item = ui->listWidget->item(i);
        QWidget* widget = ui->listWidget->itemWidget(item);         //todo：需要删除该widget防止内存泄露
        if(widget)
        {
            ListWidget* listWidgetCast = qobject_cast<ListWidget*>(widget);
            if(listWidgetCast)
            {
                QString pinName = listWidgetCast->getChineseNameLabel();
                QString functionConnect = listWidgetCast->getFuncLabel();
                QString signal = listWidgetCast->getSignalLabel();
                QString hardConnect = listWidgetCast->getHardwareConnectLabel();
                IOData* data = new IOData(pinName,functionConnect,signal,hardConnect);
                if(type == INPUT) inputData[cardIdx][i] = data;
                else
                {
                    outputData[cardIdx][i] = data;
                }
            }
        }
    }
    //写入之后自动跳转到下一页，加载下一页的数据
    ++cardIdx;
    ui->listWidget->clear();    //清除当前页面数据          todo:这里只是清空了界面数据，但是自定义数据不会释放
}

//初始化电机以及工位
void IODialog::onInitMotorBtnClicked()
{
    //读取对应的文件，将电机数量置为-1，工位开启置为0，工位数置-1
    QString folderPath = ui->filePathLabel->text();
    if(folderPath.isEmpty()) return;
    //初始化电机数量
    QString motorFilePath = folderPath + "/motor_num.ini";
    modifyMotorAndStationFile(motorFilePath,"[MOTOR_NUM]",-1);
    //初始化工位
    QString stationPath = folderPath + "/NortechSystemData.ini";
    modifyMotorAndStationFile(stationPath,"[GONGWEIKAIQI]",0);
    modifyMotorAndStationFile(stationPath,"[GONGWEISHUNXU]",-1);
}

//上一页按钮点击
void IODialog::onPrevPageBtnClicked()
{
    if(cardIdx == 0) return;
    --cardIdx;
    qDebug() << "cardIdx: " << cardIdx;
    if(type == INPUT)
    {
        changePage(inputData,cardIdx);
    }
    else
        changePage(outputData,cardIdx);
}

//下一页按钮点击
void IODialog::onNextPageBtnClicked()
{
    //如果当前页没有将数据写入数组中，不允许切换到下一页，否则切换回来的时候会越界访问
    if(type == INPUT)
    {
        if(curCardNumIdx < curCardNum)
        {
            //这里没有写完该页，不允许切页
            QMessageBox::warning(NULL,"Warning","Please enter the full content and then jump to next page");
            return;
        }
        if(curCardNum != 0)     ++cardIdx;
        changePage(inputData,cardIdx);
    }
    else
    {
        if(curCardNumIdx < curCardNum)
        {
            //这里没有写完该页，不允许切页
            QMessageBox::warning(NULL,"Warning","Please enter the full content and then jump to next page");
            return;
        }
        if(curCardNum != 0)     ++cardIdx;
        changePage(outputData,cardIdx);
    }
}

void IODialog::onModifyCardNumBtnClicked()
{
    QString text = ui->cardNumEdit->text();
    curCardNum = text.toInt();
    //给当前行数组进行空间调整
    if(type == INPUT)
    {
        resizeVector(inputData);
    }
    else
    {
        resizeVector(outputData);
    }
}

//自动化读取excel中的数据
void IODialog::onLoadXlsxBtnClicked()
{
    //1.读取文件内容中的引脚定义，然后把对应的内容加载到输入输出数组中

    //todo...

    //2.读取数组内容，将对应的内容配置完成并加载到界面中,这里加载输入的内容即可
    foreach (const QVector<IOData*>& row , inputData)
    {
        foreach (const IOData* ioData , row)
        {
            addItem(ioData);
        }
    }
}

//类型改变之后触发
void IODialog::onComboBoxIndexChanged()
{
    //改变类型，加载数据
    type = type == INPUT ? OUTPUT : INPUT;
    cardIdx = 0;
    curCardNumIdx = 0;
    ui->listWidget->clear();    //todo: 需要去清空自定义数据
    if(type == INPUT)
        changePage(inputData,0);
    else
        changePage(outputData,0);
}

//修改数组中的数据
void IODialog::onLabelTextChanged(const QString &label, const QString &hardwareStr)
{
    //1.解析对应的行列
    // 使用 split 方法按 '.' 分割字符串
    QStringList parts = hardwareStr.split('.');
    int row = 0,col = 0;
    // 检查分割后的部分是否足够
    if (parts.size() >= 6)
    {
        QString number1 = parts[3];  // 获取第 4 个部分（索引为 3）
        QString number2 = parts[5];  // 获取第 6 个部分（索引为 5）
        row = number1.toInt() - 41;
        col = number2.toInt();
        qDebug() << "Number 1:" << number1;
        qDebug() << "Number 2:" << number2;
    }
    else
    {
        qDebug() << "Input string does not have enough parts.";
    }
    //2.修改数组中的内容
    if(type == INPUT) modifyVectorByIndex(inputData,row,col,label);
    else modifyVectorByIndex(outputData,row,col,label);
}

IODialog::~IODialog()
{
    insertPinIntoDataBase();
    loadDataIntoFile();
    dataBase.close();
    delete ui;
}
